package org.grow.present.service;

import com.fasterxml.jackson.databind.ObjectMapper;
import okhttp3.*;
import org.grow.present.properties.BaiduProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.Base64;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class BaiduAIService {

    @Autowired
    private BaiduProperties baiduProperties;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private OkHttpClient client;
    @Autowired
    private ObjectMapper objectMapper;
    public static final String BaiduFaceKey = "Baidu:Face";
    public static final String BaiduWordKey = "Baidu:Word";
    public static final String accessTokenUrl = "https://aip.baidubce.com/oauth/2.0/token";
    public static final String faceAddUrl = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/user/add";
    public static final String faceSearchUrl = "https://aip.baidubce.com/rest/2.0/face/v3/search";
    public static final String bankCardUrl = "https://aip.baidubce.com/rest/2.0/ocr/v1/bankcard";
    public static final String idCardUrl = " https://aip.baidubce.com/rest/2.0/ocr/v1/idcard";

    public String refreshWordAccessToken() throws IOException {

        FormBody formBody = new FormBody.Builder()
                .add("client_id", baiduProperties.getWordAccessKey())
                .add("client_secret", baiduProperties.getWordSecretKey())
                .add("grant_type", "client_credentials")
                .build();

        Request request = new Request.Builder()
                .post(formBody)
                .url(accessTokenUrl)
                .build();

        Response response = client.newCall(request).execute();
        String res = response.body().string();
        Map<String, Object> map = objectMapper.readValue(res, Map.class);
        String accessToken = map.get("access_token").toString();
        ValueOperations<String, String> ops =
                stringRedisTemplate.opsForValue();
        ops.set(BaiduWordKey, accessToken, 5, TimeUnit.MINUTES);

        return accessToken;
    }

    public String refreshFaceAccessToken() throws IOException {
        FormBody formBody = new FormBody.Builder()
                .add("client_id", baiduProperties.getFaceAccessKey())
                .add("client_secret", baiduProperties.getFaceSecretKey())
                .add("grant_type", "client_credentials")
                .build();

        Request request = new Request.Builder()
                .post(formBody)
                .url(accessTokenUrl)
                .build();

        Response response = client.newCall(request).execute();
        String res = response.body().string();
        Map<String, Object> map = objectMapper.readValue(res, Map.class);
        String accessToken = map.get("access_token").toString();
        ValueOperations<String, String> ops =
                stringRedisTemplate.opsForValue();
        ops.set(BaiduFaceKey, accessToken, 8, TimeUnit.MINUTES);
        return accessToken;
    }

    public String forceGetWordAccessToken() throws IOException {
        ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();
        String s = ops.get(BaiduWordKey);
        if (s == null) {
            s = this.refreshWordAccessToken();
        }
        return s;
    }

    public String forceGetFaceAccessToken() throws IOException {
        ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();
        String s = ops.get(BaiduFaceKey);
        if (s == null) {
            s = this.refreshFaceAccessToken();
        }
        return s;
    }

    //    人脸注册
    public Map faceReg(byte[] image, String UID) throws IOException {
        String base64Image = Base64.getEncoder().encodeToString(image);
        String accessToken = this.forceGetFaceAccessToken();


        FormBody formBody = new FormBody.Builder()
                .add("image", base64Image)
                .add("image_type", "BASE64")
                .add("group_id", baiduProperties.getFaceGroupId())
                .add("user_id", UID)
                .build();
        Request request = new Request.Builder()
                .url(faceAddUrl + "?access_token=" + accessToken)
                .post(formBody)
                .build();
        Response response = client.newCall(request).execute();
        String res = response.body().string();
        Map map = objectMapper.readValue(res, Map.class);
        return  map;
    }

    public Map faceSearch(byte[] image, String UID) throws IOException {
        String base64Image = Base64.getEncoder().encodeToString(image);
        String accessToken = this.forceGetFaceAccessToken();
        FormBody formBody = new FormBody.Builder()
                .add("image", base64Image)
                .add("image_type", "BASE64")
                .add("group_id_list", baiduProperties.getFaceGroupId())
                .add("user_id", UID)
                .build();
        Request request = new Request.Builder()
                .url(faceSearchUrl + "?access_token=" + accessToken)
                .post(formBody)
                .build();
        Response response = client.newCall(request).execute();
        String res = response.body().string();
        Map map = objectMapper.readValue(res, Map.class);
        return  map;
    }

    public Map bankCardOcr(byte[] image) throws IOException {
        String base64Image = Base64.getEncoder().encodeToString(image);
//        System.out.println(base64Image);
        String accessToken = this.forceGetWordAccessToken();
        FormBody formBody = new FormBody.Builder()
                .add("image", base64Image)
                .build();
        Request request = new Request.Builder()
                .url(bankCardUrl + "?access_token=" + accessToken)
                .post(formBody)
                .build();
        Response response = client.newCall(request).execute();
        String res = response.body().string();
        Map map = objectMapper.readValue(res, Map.class);
        return map;
    }
    public Map idCardOcr(byte[] image, String frontOrback) throws IOException {
        String base64Image = Base64.getEncoder().encodeToString(image);
//        System.out.println(base64Image);
        String accessToken = this.forceGetWordAccessToken();
        FormBody formBody = new FormBody.Builder()
                .add("image", base64Image)
                .add("id_card_side", frontOrback)
                .build();
        Request request = new Request.Builder()
                .url(idCardUrl + "?access_token=" + accessToken)
                .post(formBody)
                .build();
        Response response = client.newCall(request).execute();
        String res = response.body().string();
        Map map = objectMapper.readValue(res, Map.class);
        return map;
    }
}
